/**
 * @file   test_surface.cpp
 * @author HirasawaYui <yui@Ubuntu18-04>
 * @date   Sat Dec 12 11:52:14 2020
 * 
 * @brief  
 * 
 * 
 */
#include "MultigridSolver.h"
#include "Surface.h"
#include "FEMSpace.h"
#include <typeinfo>
#include <math.h>
#include <ctime>
#define pi 4.0*atan(1.0)
double f(double *p)
{
    return 2 * pi*  pi* sin(pi * p[0]) * sin(pi * p[1]);
}

double bc(double *p)
{
    return sin(pi * p[0]) * sin(pi * p[1]);
}

double f2(double *p)
{
    return 2 * pi*  pi* cos(pi * p[0]) * cos(pi * p[1]);
}

double bc2(double *p)
{
    return cos(pi * p[0]) * cos(pi * p[1]);
}


int main(int argc, char* argv[])
{
    //g++ -o main test_surface.cpp -std=c++11 -I /usr/include/eigen3/ ./include/tinyxml2.cpp -g
    int n = 2;    
    RectangleDomain* r = new RectangleDomain({{0,0},{1,0},{1,1},{0,1}});
    std::vector<Boundary<2> > B = r->boundary();
    //Mesh<2>* m = new P1Mesh(r,{POW2(n), POW2(n)});
    //Element<2>* e = new Triangular_1_Element();
    Mesh<2>* m = new Q1Mesh(r,{POW2(n), POW2(n)});
    Element<2>* e = new Quadrilateral_1_Element();
    //Mesh<2>* m = new Q2Mesh(r,{POW2(n), POW2(n)});
    //Element<2>* e = new Quadrilateral_2_Element();
    //Mesh<2>* m = new P2Mesh(r,{POW2(n), POW2(n)});
    //Element<2>* e = new Triangular_2_Element();
    Equation<2>* equ = new PossionEquation<2>();
    equ ->SetBoundaryConditionFunction(bc);
    equ ->SetRightHandsTermFunction(f);
    BoundaryFunction<2> * bf = new Dirichlet<2>(bc,B);
    BoundaryCondition<2> bfc;
    bfc.add(bf);
    Possion_2D possionproblem(m,e,equ,bfc);
    possionproblem.AssembleStiffMatrix();
    possionproblem.AssembleRightHandsTerm();
    //possionproblem.DealWithBoubdaryCondition();
    //P1_MGSolver<Eigen::SparseMatrix<double> > Solver(possionproblem.A(), possionproblem.Rhs(), bc, m, n);
    Q1_MGSolver<Eigen::SparseMatrix<double> > Solver(possionproblem.A(), possionproblem.Rhs(), bc, m, n);
    //Q2_MGSolver<Eigen::SparseMatrix<double> > Solver(possionproblem.A(), possionproblem.Rhs(), bc2, m, n);
    //P2_MGSolver<Eigen::SparseMatrix<double> > Solver(possionproblem.A(), possionproblem.Rhs(), bc, m, n);
    Solver.compute(possionproblem.A());
    Solver.setTolerance(1e-12);
    VectorXd u = Solver.Solve();
    Surface<2> S(m,e,u);
    S.WriteVTKData("surface");
    S.WriteVTKData3D("surface");
    S.WriteVTUData("surface");
    S.WriteVTUData3D("surface");
    //编译时加上 -I .\include\tinyxml2.cpp
    delete m;
    delete equ;
    delete e;
    return 0;
}
